
import { _decorator, Component, Node,Prefab, instantiate, math ,Vec3, BoxCollider, macro, Label,Animation, AudioSource} from 'cc';
import { Bullet } from '../Bullet/bullet';
import { BulletProp } from '../Bullet/bulletProp';
import { EnemyPlane } from '../plane/EnemyPlane';
import { SelfPlane } from '../plane/selfPlane';
import { AudioManager } from './audioManager';
import { Constant } from './Constant';
import { PoolManager } from './PoolManager';
const { ccclass, property } = _decorator;

@ccclass('GameManager')
export class GameManager extends Component {
   //关联玩家飞机和所有的子弹
   @property(SelfPlane) 
   public playerPlane:SelfPlane=null;
   @property(Prefab)
   public bullet01:Prefab=null;
   @property(Prefab)
   public bullet02:Prefab=null;
   @property(Prefab)
   public bullet03:Prefab=null;
   @property(Prefab)
   public bullet04:Prefab=null;
   @property(Prefab)
   public bullet05:Prefab=null;
   //prop
   @property(Prefab)
   public bulletPropM:Prefab=null;
   @property(Prefab)
   public bulletPropH:Prefab=null;
   @property(Prefab)
   public bulletPropS:Prefab=null;
   @property
   public  bulletPropSpeed=0.3;

   @property
   public  shootTime=0.3;
   @property
   public bulletSpeed=1;
   @property(Node) 
   public  bulletRoot:Node=null;   //子弹管理节点 
   //enemy
   @property(Prefab)
   public enemy01:Prefab=null;
   @property(Prefab)
   public enemy02:Prefab=null;
   @property
   public createEnemyTime=1;//敌人飞机生成时间
   @property
   public  enemy1Speed=0.5;
   @property
   public  enemy2Speed=0.7;
   @property(Prefab)
   public EnemyExplode:Prefab=null;

   //ui
   @property(Node)
   public gamePage:Node=null;
   @property(Node)
   public gaemoverPage:Node=null;
   @property(Label)
   public gameScore:Label=null;
   @property(Label)
   public gameOverScore:Label=null;

   //audio
   @property(AudioManager)
   public audioEffect:AudioManager=null;
   @property(Animation)
   public overAnim:Animation=null;
   public  isGameStart=false;

   private _currShootTime=0;
   private  _isShooting=false;
   private  _currCreateEnemyTime=0;
   private  _combinationInterval=Constant.Combination.PLAN1;                              //组合的间隔状态
   private _bulletType=Constant.BulletPropType.BULLET_M;
   private _score=0;
   start () 
   {
        this._init();
   }
  
    
    update (deltaTime: number)
    {
        if(!this.isGameStart)
        {
            return;
        }
        if(this.playerPlane._isDie)
        {
            this.gameOver();
            return; 
        }
        this._currShootTime+=deltaTime;
        if(this._isShooting&&this._currShootTime>this.shootTime)
        {
            if(this._bulletType===Constant.BulletPropType.BULLET_H)
            {
                this.createPlayerBulletH();
            }
            else if(this._bulletType===Constant.BulletPropType.BULLET_S)
            {
                this.createPlayerBulletS();
            }
            else
            {
                this.createPlayerBulletM();
            }

                const name='bullet'+(this._bulletType%2+1);
                this.playerAudioEffect(name);

                this._currShootTime=0;
        }
        this._currCreateEnemyTime+=deltaTime;
        if(this._combinationInterval===Constant.Combination.PLAN1)
        {
              if(this._currCreateEnemyTime>this.createEnemyTime)
               {
                   this.createEnemyPlan();
                   this._currCreateEnemyTime=0;
               }
        }
        else if(this._combinationInterval===Constant.Combination.PLAN2)
        {
            if(this._currCreateEnemyTime>this.createEnemyTime*3)
            {
                const randomCombination=math.randomRangeInt(1,3);
                if(randomCombination===Constant.Combination.PLAN2)
                {
                    this.createCombination01();
                }
              else 
                {
                    this.createEnemyPlan();
                }
                this._currCreateEnemyTime=0;
            }
        }
        else
        {
            if(this._currCreateEnemyTime>this.createEnemyTime*2)
            {
                const randomCombination=math.randomRangeInt(1,4);
                if(randomCombination===Constant.Combination.PLAN2)
                {
                    this.createCombination01();
                }
                else if(randomCombination===Constant.Combination.PLAN3)
                {
                    this.createCombination02();
                }
              else 
                {
                    this.createEnemyPlan();
                }
                this._currCreateEnemyTime=0;
            }
        }
    }

    public createPlayerBulletM()
    {
       //const bullet=instantiate(this.bullet01);//调用实例
       const bullet=PoolManager.instance().getNode(this.bullet01,this.bulletRoot);
      // bullet.setParent(this.bulletRoot);  //buttleManager
       const pos=this.playerPlane.node.position;  //设置子弹应该在的位置
       bullet.setPosition(pos.x,pos.y,pos.z-7);//采用飞机位置的X和Y
       const bulletComp = bullet.getComponent(Bullet)//这个bulletComp为空  this.node
       bulletComp.show(this.bulletSpeed,false);
    
    }

    public createPlayerBulletH()
    {
       const pos=this.playerPlane.node.position;  //设置子弹应该在的位置
       //left
       //const bullet1=instantiate(this.bullet03);//调用实例
       const bullet1=PoolManager.instance().getNode(this.bullet03,this.bulletRoot);
       //bullet1.setParent(this.bulletRoot);  //buttleManager
       bullet1.setPosition(pos.x-2.5,pos.y,pos.z-7);
       const bulletComp1 = bullet1.getComponent(Bullet)//这个bulletComp为空  this.node
       bulletComp1.show(this.bulletSpeed,false);
        //right
        //const bullet2=instantiate(this.bullet03); 
        const bullet2=PoolManager.instance().getNode(this.bullet03,this.bulletRoot);
        //bullet2.setParent(this.bulletRoot);   
        bullet2.setPosition(pos.x+2.5,pos.y,pos.z-7);
        const bulletComp2 = bullet2.getComponent(Bullet) 
        bulletComp2.show(this.bulletSpeed,false);
    
    }

    public createPlayerBulletS()
    {
       const pos=this.playerPlane.node.position;  
       //middle
       //const bullet=instantiate(this.bullet05);
       const bullet=PoolManager.instance().getNode(this.bullet05,this.bulletRoot);
       //bullet.setParent(this.bulletRoot);  
       bullet.setPosition(pos.x,pos.y,pos.z-7);
       const bulletComp = bullet.getComponent(Bullet);
       bulletComp.show(this.bulletSpeed,false);
       //left
       //const bullet1=instantiate(this.bullet05);
       const bullet1=PoolManager.instance().getNode(this.bullet05,this.bulletRoot);
      // bullet1.setParent(this.bulletRoot);  
       bullet1.setPosition(pos.x-4,pos.y,pos.z-7);
       const bulletComp1 = bullet1.getComponent(Bullet);
       bulletComp1.show(this.bulletSpeed,false,Constant.Direction.LEFT);
       //right
       //const bullet2=instantiate(this.bullet05);
       const bullet2=PoolManager.instance().getNode(this.bullet05,this.bulletRoot);
       //bullet2.setParent(this.bulletRoot);  
       bullet2.setPosition(pos.x+4,pos.y,pos.z-7);
       const bulletComp2 = bullet2.getComponent(Bullet);
       bulletComp2.show(this.bulletSpeed,false,Constant.Direction.RIGHT);
       // console.log('PODSSSSSSl:',pos);
    
    }

    public createEnemyBullet(tartgetPos:Vec3)
    {
        //const bullet =instantiate(this.bullet01);  //预制的子弹放到场景里面 过程叫实例 instantiate实例接口
        const bullet=PoolManager.instance().getNode(this.bullet02,this.bulletRoot);
        //bullet.setParent(this.bulletRoot);            //实例出来的对象 放在场景
        bullet.setPosition(tartgetPos.x,tartgetPos.y,tartgetPos.z+6);
        const bullteComp=bullet.getComponent(Bullet);
        bullteComp.show(1,true);

        const colliderComp=bullet.getComponent(BoxCollider);
        colliderComp.setGroup(Constant.CollisionType.ENEMY_BULLET);  //设置可以碰撞分组 和掩码
        colliderComp.setMask(Constant.CollisionType.SELF_PLAN);
    }

    public createEnemyPlan()
    { 
          const whichEnemy =math.randomRangeInt(1,3);
          let Prefab:Prefab=null;
          let speed=0;
          if(whichEnemy===Constant.EnemyPlan.TYPE1)
          {
              Prefab=this.enemy01;
              speed=this.enemy1Speed;
          }else
          {  
              Prefab=this.enemy02;
              speed=this.enemy2Speed;
          }
  
          //const enemy=instantiate(Prefab);
          const enemy=PoolManager.instance().getNode(Prefab,this.node);
          //enemy.setParent(this.node);
          const enemyComp=enemy.getComponent(EnemyPlane);
          enemyComp.show(this,speed,true);
          
          const randomPos=math.randomRangeInt(-25,26);
          enemy.setPosition(randomPos,0,-50); 
      }
  
      public createCombination01()
      {
          const enemyArray=new Array<Node>(5);
          for(let i=0;i<enemyArray.length;i++)
          {
              //enemyArray[i]=instantiate(this.enemy01);
              enemyArray[i]=PoolManager.instance().getNode(this.enemy01,this.node);
              const element=enemyArray[i];
              //element.parent=this.node;
              element.setPosition(-20+i*10,0,-50);
              const enemyComp=element.getComponent(EnemyPlane);
              enemyComp.show(this,this.enemy1Speed,false);
          }
     }

     public createBulletProp()
     {
        const randomPorp=math.randomRangeInt(1,4);
        let prefab:Prefab=null;
        if(randomPorp===Constant.BulletPropType.BULLET_H)
        {
            prefab=this.bulletPropH;
        }
        else if(randomPorp===Constant.BulletPropType.BULLET_S)
        {
            prefab=this.bulletPropS;
        }
         else
         {
            prefab=this.bulletPropM;
         }

         //const prop=instantiate(prefab);
         const prop=PoolManager.instance().getNode(prefab,this.node);
       //  prop.setParent(this.node);
         prop.setPosition(15,0,-50);
         const propComp=prop.getComponent(BulletProp);
         propComp.show(this,-this.bulletPropSpeed)
     }

     public createCombination02()
     {
         const enemyArray=new Array<Node>(7);
         const CombinationPos =
         [
             -21,0,-60,
             -14,0,-55,
             -7,0,-50,
             0,0,-45,
             7,0,-50,
             14,0,-55,
             21,0,-60,
         ];
 
         for(let i=0;i<enemyArray.length;i++)
         {
             //enemyArray[i]=instantiate(this.enemy02);
             enemyArray[i]=PoolManager.instance().getNode(this.enemy02,this.node);
             const element=enemyArray[i];
             //element.parent=this.node;
             const startIndex=i*3;  //数组每3个一组
             element.setPosition(CombinationPos[startIndex],CombinationPos[startIndex+1],CombinationPos[startIndex+2]);
              const enemyComp=element.getComponent(EnemyPlane);
              enemyComp.show(this,this.enemy2Speed,false);
         }
 
         
     }

     public createBulletEffect(pos:Vec3)
     { 
         const effect=PoolManager.instance().getNode(this.EnemyExplode,this.node);
         effect.setPosition(pos);
     }

     public changeBulletType(type:number)
     {
        this._bulletType=type;
     }
     public  addScore()
     {
        this._score++;
        this.gameScore.string=this._score.toString();
     }

     public returnMain()
     {
        this._currShootTime=0;
        this._currCreateEnemyTime=0;
        this. _combinationInterval=Constant.Combination.PLAN1;                              //组合的间隔状态
        this. _bulletType=Constant.BulletPropType.BULLET_M;
        this.playerPlane.node.setPosition(0,0,15);
        this._score=0;
    }

     public reStart()
     {
        this.gameStart();
        this._currShootTime=0;
        this._currCreateEnemyTime=0;
        this. _combinationInterval=Constant.Combination.PLAN1;                              //组合的间隔状态
        this. _bulletType=Constant.BulletPropType.BULLET_M;
        this.playerPlane.node.setPosition(0,0,15);
     }

     public gameStart()
     {
        this.isGameStart=true;
        this._changePlanMode();
        this._score=0;
        this.gameScore.string=this._score.toString();
        this.playerPlane._init();
        
     }

     public gameOver()
     {
         this.overAnim.play();
         this.isGameStart=false;
         this.gamePage.active=false;
         this.gaemoverPage.active=true;
         this.gameOverScore.string=this._score.toString();
         this._isShooting=false;
         this.unschedule(this._modechanged);//取消定时器
         this._destoryAll();
         //this.playerPlane._init();

     }

    public isShooting(value:boolean)
    {
       this._isShooting=value;
    }

     private _init()
    {
        this._currShootTime=this.shootTime;
    }

     private _changePlanMode()
    {
         this.schedule(this._modechanged,10,macro.REPEAT_FOREVER);//进来3次 每10秒改变一次状态  计时器
    }

    private _modechanged()
    {
        this._combinationInterval++;
        this.createBulletProp();
    }

    public _destoryAll()
    {
        let _children =this.node.children;
        let lenght=_children.length;
        let i =0;
        for ( i = lenght-1; i>=0; i--) {
            const child =_children[i];
            //child.destroy();
             PoolManager.instance().putNode(child);
        }

        _children =this.bulletRoot.children;
        lenght=_children.length;
        for ( i = lenght-1; i>=0; i--) {
            const child =_children[i];
            //child.destroy();
            PoolManager.instance().putNode(child);
        }

    }

    public playerAudioEffect(name:string)
    {
        this.audioEffect.play(name);
    }

}

/**
 * [1] Class member could be defined like this.
 * [2] Use `property` decorator if your want the member to be serializable.
 * [3] Your initialization goes here.
 * [4] Your update function goes here.
 *
 * Learn more about scripting: https://docs.cocos.com/creator/3.0/manual/en/scripting/
 * Learn more about CCClass: https://docs.cocos.com/creator/3.0/manual/en/scripting/ccclass.html
 * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.0/manual/en/scripting/life-cycle-callbacks.html
 */
